﻿using System;
using System.ComponentModel;

using SharpGL.Media3D;

namespace SharpGL.SceneGraph.Primitives.SmartAxies
{
    [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
    public class AxisTicks : INotifyPropertyChanged
    {
        #region Private Fields
        
        private bool visible = true;
        private GLColor color = new GLColor(1.0f, 1.0f, 1.0f, 1.0f);
        private float width = 1.0f;
        private float lengthPercent = 0.005f;
        private Vector3D direction = new Vector3D(0.0f, 0.0f, 1.0f);
        private bool roundFirstTickValue = true;
        
        #endregion Private Fields

        #region Protected Methods

        /// <summary>
        /// Call this function to do the PropertyChanged event.
        /// </summary>
        protected virtual void NotifyPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion Protected Methods

        #region Public Constructors

        public AxisTicks()
        {
        }

        #endregion Public Constructors

        #region Internal Methods

        internal void Render(OpenGL gl, Point3D[] vertices)
        {
            if ((!OpenGL.IsValidContext(gl)) || (vertices == null) || (vertices.Length <= 0) || ((vertices.Length % 2) != 0))
                throw new ArgumentException();

            if (Visible)
            {
                gl.PushAttrib(Enumerations.AttributeMask.Current | Enumerations.AttributeMask.Line | Enumerations.AttributeMask.Enable);
                {
                    byte[] isLightingEnable = new byte[1];
                    gl.GetBooleanv(Enumerations.GetTarget.Lighting, isLightingEnable);
                    if (isLightingEnable[0] != 0)
                        gl.Enable(OpenGL.GL_COLOR_MATERIAL);

                    gl.LineWidth(Width);
                    gl.Color(Color);

                    gl.Begin(Enumerations.BeginMode.Lines);
                    {
                        foreach (Point3D vertex in vertices)
                            gl.Vertex(vertex);
                    }
                    gl.End();
                }
                gl.PopAttrib();
            }
        }

        #endregion Internal Methods

        #region Public Events

        [Description("Called when properties has been changed."), Category("SharpGL")]
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion Public Events

        #region Public Properties

        [Description("Visible"), Category("Axis ticks")]
        public bool Visible
        {
            get { return visible; }
            set
            {
                if (visible != value)
                {
                    visible = value;

                    NotifyPropertyChanged("Visible");
                }
            }
        }

        [Description("Color"), Category("Axis ticks")]
        public GLColor Color
        {
            get { return color; }
            set
            {
                if (color != value)
                {
                    color = value;

                    NotifyPropertyChanged("Color");
                }
            }
        }

        [Description("Width"), Category("Axis ticks")]
        public float Width
        {
            get { return width; }
            set
            {
                if (width != value)
                {
                    width = Math.Abs(value);

                    NotifyPropertyChanged("Width");
                }
            }
        }

        [Description("LengthPercent"), Category("Axis ticks")]
        public float LengthPercent
        {
            get { return lengthPercent; }
            set
            {
                if (lengthPercent != value)
                {
                    lengthPercent = value;

                    NotifyPropertyChanged("LengthPercent");
                }
            }
        }

        [Description("Direction"), Category("Axis ticks")]
        public Vector3D Direction
        {
            get { return direction; }
            set
            {
                if (direction != value)
                {
                    value.Normalize();
                    direction = value;

                    NotifyPropertyChanged("Direction");
                }
            }
        }

        [Description("RoundFirstTickValue"), Category("Axis ticks")]
        public bool RoundFirstTickValue
        {
            get { return roundFirstTickValue; }
            set
            {
                if (roundFirstTickValue != value)
                {
                    roundFirstTickValue = value;

                    NotifyPropertyChanged("RoundFirstTickValue");
                }
            }
        }

        #endregion Public Properties
    }
}
